package org.opens.javaskill.design;

import java.util.ArrayList;
import java.util.List;

/**
 * 说明:
 *      1. 中介者模式的demo
 */
public class MediatorPattern {

    /**
     * 说明:
     *      1. 在这个模式中, 只要注册中心中的任意一个对象执行了send方法, 都会触发这个注册中心中所有对象的receive方法.
     *          - 可以理解为center是一个公共电话薄, 任意一个用户的信息发生变化后, center都需要把这个用户的改变同步到其他用户手机上.
     *
     */
    public static void main(String[] args) {
        MyServiceCenter center = new MyServiceCenter();

        MyTenantPerson s1 = new MyTenantPerson("s1");
        MyTenantPerson s2 = new MyTenantPerson("s2");
        MyTenantPerson s3 = new MyTenantPerson("s3");
        MyTenantPerson s4 = new MyTenantPerson("s4");
        MyTenantPerson s5 = new MyTenantPerson("s5");

        center.register(s1);
        center.register(s2);
        center.register(s3);
        center.register(s4);
        center.register(s5);

        s1.send();
        s2.send();
    }

}

interface ServiceCenter {

    // TenantPerson将自己注册到ServiceCenter中
    void register(TenantPerson tenantPerson);

    // 转发消息
    void relay(TenantPerson tenantPerson);

}

abstract class TenantPerson {

    // 当前对象所注册的ServiceCenter
    protected ServiceCenter serviceCenter;

    public void setServiceCenter(ServiceCenter serviceCenter) {
        this.serviceCenter = serviceCenter;
    }

    // 接受消息
    abstract void receive();

    // 发送消息
    abstract void send();

}

class MyServiceCenter implements ServiceCenter {

    private List<TenantPerson> registerTenantList = new ArrayList<>();

    @Override
    public void register(TenantPerson tenantPerson) {
        if ( !registerTenantList.contains(tenantPerson) ) {
            registerTenantList.add(tenantPerson);
            tenantPerson.setServiceCenter(this);
        }
    }

    @Override
    public void relay(TenantPerson tenantPerson) {
        registerTenantList.forEach(x -> {
            if ( !x.equals(tenantPerson) ) {
                x.receive();
            }
        });
    }

}

class MyTenantPerson extends TenantPerson {

    private String name;

    public MyTenantPerson(String name) {
        this.name = name;
    }

    @Override
    void receive() {
        System.out.println(name + " 收到消息.");
    }

    @Override
    void send() {
        System.out.println(name + " 发送消息");
        this.serviceCenter.relay(this);
    }

}
